﻿/*********************************************************************
 * @file       sqlite.cpp
 * @brief      数据库操作类
 * @details    基于Sqlite数据库
 * @author     南樟(a2169272059@163.com)
 * @date       2025-2-10
 * @version    1.0.0
 * @copyright  a2169272059@163.com
 *********************************************************************/
#include "sqlite.h"

#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QDebug>
#include <QtSql/QSqlQuery>
#include <QList>
#include <QPair>
/**
 * @brief sqlite::sqlite 数据库构造类
 * @note 请使用openDatabase打开数据库，
 *  注意数据库要在QApplication运行之后再建立连接
 */
sqlite::sqlite() {
}
/**
 * @brief 打开数据库链接
 * @return 链接书否成功
 */
bool sqlite::openDatabase(const QString &databasePath){
    // 创建一个新的SQlite 数据库链接
    db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(databasePath);
    // 打开数据库连接
    if(!db.open()){
        qDebug()<<"无法打开数据库"<< db.lastError().text();
        return false;
    }
    qDebug()<<"数据库已成功打开";
    return true;
}

sqlite::~sqlite(){
    // 关闭数据库连接
    db.close();
    qDebug()<<"数据库已成功关闭";
}
/**
 * @brief 检查并创建周表
 * @return 周表连接是否成功
 * @note 周表不存在时会自动创建周表，但此时不会报错。
 */
bool sqlite::createTable_week_duration(){
    QSqlQuery query(db);
    bool success = query.exec(
        "CREATE TABLE IF NOT EXISTS week_duration ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT, "
        "name TEXT, "
        "on_week INTEGER CHECK (on_week BETWEEN 1 AND 7) NOT NULL,"
        "begin_time TEXT CHECK (begin_time LIKE '%:%') NOT NULL,"
        "end_time TEXT CHECK (end_time LIKE '%:%') NOT NULL,"
        "begin_date TEXT CHECK (begin_date LIKE '%-%-%') NOT NULL,"
        "end_date TEXT CHECK (end_date LIKE '%-%-%') NOT NULL"
        ");");
    if(!success){
        qDebug()<<"创建week_duration表失败"<<query.lastError().text();
        return false;
    }

    qDebug() << "week_duration表格创建成功";
    return true;
}
/**
 * @brief 检查并创建任务表
 * @return 任务表连接是否成功
 * @note 任务表不存在时会自动创建周表，但此时不会报错。
 */
bool sqlite::createTable_task(){
    QSqlQuery query(db);
    bool success = query.exec(
        "CREATE TABLE IF NOT EXISTS task ("
        "id INTEGER PRIMARY KEY AUTOINCREMENT, "
        "name TEXT, "
        "begin_date TEXT CHECK (begin_date LIKE '%-%-%') NOT NULL,"
        "end_date TEXT CHECK (end_date LIKE '%-%-%') NOT NULL,"
        "is_ok INTEGER CHECK (is_ok IN(0,1)) NOT NULL DEFAULT 0"
        ");"
    );
    if(!success){
        qDebug()<<"创建task表失败"<<query.lastError().text();
        return false;
    }

    qDebug() << "task表格创建成功";
    return true;
}
/**
 * @brief 添加任务表信息
 * @param name 任务名称
 * @param begin_date 任务开始日期
 * @param end_date 任务结束日期
 * @return 添加是否成功
 */
bool sqlite::insert_task(const QString &name,const QString &begin_date,const QString &end_date){
    QSqlQuery query(db);
    query.prepare("INSERT INTO task (name,begin_date,end_date,is_ok) VALUES(:name,:begin_date,:end_date,:is_ok)");
    query.bindValue(":name",name);    
    query.bindValue(":begin_date",begin_date);
    query.bindValue(":end_date",end_date);
    query.bindValue(":is_ok",0);
    if(!query.exec()){
        qDebug()<<"插入task数据失败："<<query.lastError().text();
        return false;
    }
    qDebug()<<"task数据插入成功";
    return true;
}
/**
 * @brief 添加周表信息
 * @param name 每周事件的名字
 * @param on_week 周几
 * @param begin_time 该事件的开始时间
 * @param end_time 该事件的结束时间
 * @return 添加是否成功
 */
bool sqlite::insert_week_duration(
    const QString &name,const qint8& on_week,
    const QString &begin_time,const QString &end_time,
    const QString &begin_date,const QString &end_date
    ){
    QSqlQuery query(db);
    query.prepare("INSERT INTO week_duration ("
                  "name,on_week,begin_time,"
                  "end_time,begin_date,end_date"
                  ") VALUES(:name,:on_week,"
                    ":begin_time,:end_time,:begin_date,:end_date)"
    );
    query.bindValue(":name",name);
    query.bindValue(":on_week",on_week);
    query.bindValue(":begin_time",begin_time);
    query.bindValue(":end_time",end_time);
    query.bindValue(":begin_date",begin_date);
    query.bindValue(":end_date",end_date);
    if(!query.exec()){
        qDebug()<<"插入week_duration数据失败："<<query.lastError().text();
        return false;
    }
    qDebug()<<"week_duration数据插入成功";
    return true;
}
/**
 * @brief 检查并创建闹钟表
 * @return 任务表连接是否成功
 * @note 闹钟表不存在时会自动创建闹钟表，但此时不会报错。
 */
bool sqlite::createTable_clock(){
    QSqlQuery query(db);
    bool success = query.exec(
        "CREATE TABLE IF NOT EXISTS clock( "
        "id INTEGER PRIMARY KEY AUTOINCREMENT, "
        "note TEXT,"
        "clock_time TEXT CHECK (clock_time LIKE '%:%') NOT NULL, "
        "enable INTEGER CHECK (enable IN(0,1)) NOT NULL DEFAULT 1, "
        "bits_week INTEGER NOT NULL DEFAULT 0"
        ");"
    );
    if(!success){
        qDebug()<<"创建clock表失败"<<query.lastError().text();
        return false;
    }
    qDebug()<<"创建clock表成功";
    return true;
}
/**
 * @brief 添加闹钟表信息
 * @param note 该闹钟的备注
 * @param time 闹铃时间
 * @param enable 开关
 * @return 是否成功
 */
bool sqlite::insert_clock(const QString &note,const QString& clock_time,const qint8& enable,const qint8 &bits_week){
    QSqlQuery query(db);
    query.prepare("INSERT INTO clock (note,clock_time,enable,bits_week) "
                  "VALUES(:note,:clock_time,:enable,:bits_week)");
    query.bindValue(":note",note);
    query.bindValue(":clock_time",clock_time);
    query.bindValue(":enable",enable);
    query.bindValue(":bits_week",bits_week);
    if(!query.exec()){
        qDebug()<<"插入clock数据失败："<<query.lastError().text();
        return false;
    }
    qDebug()<<"clock数据插入成功";
    return true;
}
/**
 * @brief 检查并创建日程表
 * @return 日程表连接是否成功
 * @note 日程表不存在时会自动创建周表，但此时不会报错。
 */
bool sqlite::createTable_day_duration(){
    QSqlQuery query(db);
    bool success = query.exec(
        "CREATE TABLE IF NOT EXISTS day_duration("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "note TEXT,"
        "begin_date TEXT CHECK (begin_date LIKE '%-%-%') NOT NULL,"
        "end_date TEXT CHECK (end_date LIKE '%-%-%') NOT NULL,"
        "begin_time TEXT CHECK (begin_time LIKE '%:%') NOT NULL,"
        "end_time TEXT CHECK (end_time LIKE '%:%') NOT NULL"
        ");"
    );
    if(!success){
        qDebug()<<"创建day_duration表失败"<<query.lastError().text();
        return false;
    }
    qDebug()<<"day_duration表格创建成功";
    return true;
}
/**
 * @brief 添加日程表信息
 * @param note 日程信息
 * @param date 具体日期
 * @param begin_time 开始时间
 * @param end_time 结束时间
 * @return 是否添加成功
 */
bool sqlite::insert_day_duration(const QString& note,const QString& begin_date,const QString& end_date,const QString& begin_time,const QString& end_time){
    QSqlQuery query(db);
    query.prepare("INSERT INTO day_duration(note,begin_date,end_date,begin_time,end_time) VALUES(:note,:begin_date,:end_date,:begin_time,:end_time)");
    query.bindValue(":note",note);
    query.bindValue(":begin_date",begin_date);
    query.bindValue(":end_date",end_date);
    query.bindValue(":begin_time",begin_time);
    query.bindValue(":end_time",end_time);
    if(!query.exec()){
        qDebug() << "插入day_duration数据失败："<<query.lastError().text();
        return false;
    }
    qDebug() << "day_duration数据插入成功";
    return true;
}
/**
 * @brief 检查并创建健康提醒表
 * @return 健康提醒表连接是否成功
 * @note 健康提醒表不存在时会自动创建周表，但此时不会报错。
 */
bool sqlite::createTable_clock_break(){
    QSqlQuery query(db);
    bool success = query.exec(
        "CREATE TABLE IF NOT EXISTS clock_break("
        "id INTEGER PRIMARY KEY AUTOINCREMENT,"
        "note TEXT,"
        "duration TEXT CHECK (duration LIKE '%:%') NOT NULL,"
        "enable INTEGER CHECK (enable IN(0,1)) NOT NULL DEFAULT 1"
        ");");
    if(!success){
        qDebug()<<"创建clock_break表失败"<<query.lastError().text();
        return false;
    }
    qDebug()<<"创建clock_break表成功";
    return true;
}
/**
 * @brief 添加健康提醒表信息
 * @param note 提醒信息
 * @param duration 提醒间隔
 * @param enable 开关
 * @return 是否添加成功
 */
bool sqlite::insert_clock_break(const QString& note,const QString& duration,const qint8& enable){
    QSqlQuery query(db);
    query.prepare("INSERT INTO clock_break(note,duration,enable) VALUES(:note,:duratino,:enable)");
    query.bindValue(":note",note);
    query.bindValue(":duratino",duration);
    query.bindValue(":enable",enable);
    if(!query.exec()){
        qDebug() << "插入clock_break数据失败："<<query.lastError().text();
        return false;
    }
    qDebug() << "clock_break数据插入成功";
    return true;
}
/**
 * @brief get_db 得到此时的数据库句柄
 * @return 数据库句柄
 */
QSqlDatabase& sqlite::get_db(){
    return db;
}
